package com.shigu.admin.action;

import com.github.wxpay.extend.MyWxPayConfig;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.shigu.MallResponse;
import com.shigu.PageResponse;
import com.shigu.account.exception.UtilsAccountException;
import com.shigu.exceptions.AdminException;
import com.shigu.trade.bo.*;
import com.shigu.trade.enums.PayWay;
import com.shigu.trade.service.TradeAdminService;
import com.shigu.trade.vo.*;
import com.shigu.weixin.service.PayApplyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("adminjson")
public class TradeAdminController {
    private static final Logger logger = LoggerFactory.getLogger(TradeAdminController.class);

    @Autowired
    TradeAdminService tradeAdminService;
    @Autowired
    PayApplyService payApplyService;


    @RequestMapping("allOrderList")
    @ResponseBody
    public PageResponse<AllOrderVo> allOrderList(AllOrderRequest request){
        return tradeAdminService.allOrderList(request.getPage(),request.getSize(),request.getTradeCode());
    }

    @RequestMapping("sendedList")
    @ResponseBody
    public PageResponse<SendVo> sendedList(SendedRequest request){
        return tradeAdminService.sendedList(request.getPage(),request.getSize(),
                                               request.getTradeCode(),request.getBuyerId(),
                                               request.getStatus(),request.getAgentId());
    }


    @RequestMapping("orderSend")
    @ResponseBody
    public MallResponse orderSend(@Valid OrderSendRequest request, BindingResult result) throws AdminException, UtilsAccountException {
        if(result.hasErrors()){
            throw new AdminException(result.getFieldError().getDefaultMessage());
        }
        return tradeAdminService.orderSend(request.getTradeCode(),request.getPostCompany(),request.getPostCode(),request.getRemark());
    }

    @RequestMapping("toSendList")
    @ResponseBody
    public PageResponse<ToSendVo> toSendList(ToSendListRequest request){
        return tradeAdminService.toSendList(request.getPage(),request.getSize(),request.getTradeCode(),request.getAgentId());
    }

    @RequestMapping("remarkOrder")
    @ResponseBody
    public MallResponse remarkOrder(@Valid RemarkOrderRequest request, BindingResult result) throws AdminException {
        if(result.hasErrors()){
            throw new AdminException(result.getFieldError().getDefaultMessage());
        }
        return tradeAdminService.remarkOrder(request.getTradeCode(),request.getRemark());
    }

    @RequestMapping("closeTrade")
    @ResponseBody
    public MallResponse closeTrade(@Valid TradeCodeRequest request, BindingResult result) throws AdminException {
        if(result.hasErrors()){
            throw new AdminException(result.getFieldError().getDefaultMessage());
        }
        return tradeAdminService.closeTrade(request.getTradeCode());
    }


    @RequestMapping("exportTradeList")
    @ResponseBody
    public MallResponse exportTradeList(HttpServletResponse response) throws UnsupportedEncodingException {
        String fileName = "全部订单"+System.currentTimeMillis()+ ".xls";
        response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        try {
            OutputStream output = response.getOutputStream();
            BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
            tradeAdminService.exportTradeList(output);
            bufferedOutPut.flush();
            bufferedOutPut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new MallResponse().success();
    }


    @RequestMapping("exportNoSend")
    @ResponseBody
    public MallResponse exportNoSend(HttpServletResponse response) throws UnsupportedEncodingException {
        String fileName = "待发货订单"+System.currentTimeMillis()+ ".xls";
        response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        try {
            OutputStream output = response.getOutputStream();
            BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
            tradeAdminService.exportNoSend(output);
            bufferedOutPut.flush();
            bufferedOutPut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new MallResponse().success();
    }

    /**
     * todo 支付回调会返回appId，需要做一个map. 为 appId，config 做value。 回调后根据appId取config做验签
     * @description 支付的回调
     * @author 郭尔
     * @date 2019-05-15 15:45
     */
    @RequestMapping("payCallBack")
    public void payCallBack(HttpServletRequest request, HttpServletResponse response) throws Exception {

        StringBuffer sb = new StringBuffer();
        String s;
        try {
            InputStream inputStream = request.getInputStream();
            try (BufferedReader in = new BufferedReader(new InputStreamReader(inputStream))) {
                while ((s = in.readLine()) != null) {
                    sb.append(s);
                }
            }
            inputStream.close();
        }catch (Exception e){
            logger.error( "" , e);
        }

        logger.error("====================支付回掉参数：" + sb.toString());
        //jsapi 会返回 appId,根据appId去获取相应的商户 key. 做验签
        MyWxPayConfig config = new MyWxPayConfig();
        Map<String, String> notifyMap = WXPayUtil.xmlToMap(sb.toString());  // 转换成map
//        ConfigMapper.getMchKey(notifyMap.get("app_id"));

        if (WXPayUtil.isSignatureValid(notifyMap, config.getKey(), WXPayConstants.SignType.MD5)) {
            // 签名正确
            // 进行处理。
            // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
           boolean success = payApplyService.dowithPayApply(notifyMap.get("return_code"),notifyMap.get("return_msg"),
                                                               notifyMap.get("total_fee"),notifyMap.get("transaction_id"),
                                                               notifyMap.get("out_trade_no"));
           //订单
            tradeAdminService.dowithTrade(notifyMap.get("out_trade_no"),success, PayWay.WXPAY);
            Map<String,String> dataMap=new HashMap<>();
            dataMap.put("return_code","SUCCESS");
            dataMap.put("return_msg","OK");
            PrintWriter writer=response.getWriter();
            writer.write(WXPayUtil.mapToXml(dataMap));
            writer.flush();
            writer.close();
        } else {
            // 签名错误，如果数据里没有sign字段，也认为是签名错误
            logger.error("非法请求："+sb.toString());
        }
    }

    @RequestMapping("changeTradeReceive")
    @ResponseBody
    public MallResponse changeTradeReceive(ChangeReceiveRequest request) throws AdminException {
        return tradeAdminService.changeTradeReceive(request.getTradeCode(),request.getProvName(),request.getCityName(),
                request.getAreaName(),request.getReceiveName(),request.getReceiveAddress(),request.getReceiveTelephone());
    }

    @RequestMapping("tradeBonus")
    @ResponseBody
    public TradeBonusResponse tradeBonus(TradeCodeRequest request){
        return tradeAdminService.tradeBonus(request.getTradeCode());
    }

    @RequestMapping("refundTrade")
    @ResponseBody
    public MallResponse tradeWxRefund(TradeCodeRequest request) throws Exception {
        return tradeAdminService.tradeWxRefund(request.getTradeCode());
    }

    @RequestMapping("queryWxRefund")
    @ResponseBody
    public RefundResultResponse queryWxRefund(TradeCodeRequest request) throws Exception {
        return tradeAdminService.queryWxRefund(request.getTradeCode());
    }

}
